/* Name:	Rio Atmadja
   Program:	queue_array.h
*/

#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <fstream>

/*-------------------------------------------------------------------*/
/*   *queue_array() --> default constractor for this class	     */
/*-------------------------------------------------------------------*/
template <class Type>
queue_array<Type>::queue_array() {

	MAXSIZE = 1000; //set max size to 1000 elements
	front = 0; //set front to point to the first element
	back  = MAXSIZE-1; //set back to point to the first element
	size  = 0; //initialize size to zero 
	list = new Type[MAXSIZE]; //create a dynamic array to hold the queue
}

/*-------------------------------------------------------------------*/
/*   *~queue_array() --> default destractor for this class	     */
/*-------------------------------------------------------------------*/
template <class Type>
queue_array<Type>::~queue_array() {

	delete [] list; //destroy the list 
	size *= 0; //set the size back to zero
}

/*-------------------------------------------------------------------*/
/*   *empty() --> check if the queue is empty 		             */
/*-------------------------------------------------------------------*/
template <class Type>
bool queue_array<Type>::empty() {

	return ( size == 0 ); //return size equal to zero 
}

/*--------------------------------------------------------------------*/
/*    *full() --> check wheter the queue is full or not		      */
/*--------------------------------------------------------------------*/
template <class Type>
bool queue_array<Type>::full() {
	
	return ( size == MAXSIZE ); 
}

/*--------------------------------------------------------------------*/
/*   *push(Type data) --> append data to the queue		      */
/*   Type data 	      --> data to be inserted			      */
/*--------------------------------------------------------------------*/
template <class Type>
void queue_array<Type>::push(Type data) {

	if( !full() ) {
	
		if( empty() ) { //if queue is empty add at the begining of the queue
			
			back = 0;
			list[back] = data;
			size++;

		} else {
	
			back++;
			list[back] = data; //put the data into the queue
			size++; //increment the queue
		}
	
	} else {
		
		cout << " cannot add any more element to the queue" << endl;
	}
}

/*--------------------------------------------------------------------*/
/*   *size() --> return the size of the queue			      */
/*--------------------------------------------------------------------*/
template <class Type>
int queue_array<Type>::length() {

	return size;
}

/*---------------------------------------------------------------------*/
/*  *print() --> print the whole elements of the queue to the console  */
/*---------------------------------------------------------------------*/
template <class Type> 
void queue_array<Type>::print() {

	cout << " [ ";
	for(int i=0; i<size; i++) {
		cout << list[i] << " ";
	}
	cout << " ] " << endl;
}

/*----------------------------------------------------------------------*/
/*   *pop() --> delete an element from the queue 			*/
/*----------------------------------------------------------------------*/
template <class Type>
void queue_array<Type>::pop() {

	if( !empty() ) { 
		
		front++; //increment the front pointer position
		size--; //decrement the size	

	} else {
		
		cout << "Cannot remove from an empty queue" << endl;
	
	}
}

/*-----------------------------------------------------------------------*/
/*    *first() --> return the front element 				 */
/*-----------------------------------------------------------------------*/
template <class Type>
Type queue_array<Type>::first() {

	if( !empty() ) {
		return list[front];		
		
	} else {
		
		cout << "no element to be returned" << endl;
	}
}

/*-----------------------------------------------------------------------*/
/*   *last()  --> return the last element in the queue			 */
/*-----------------------------------------------------------------------*/
template <class Type> 
Type queue_array<Type>::last() {
	
	if( !empty() ) {
	
		return list[back];
 	
	} else {

		cout << "no element to be returned" << endl;
	}
}

/*-----------------------------------------------------------*/
/*  *shuffle(Type data) --> shuffle the data elements        */
/*-----------------------------------------------------------*/
template <class Type>
void queue_array<Type>::shuffle() {
    
        for( int i=0; i<length(); i++) {
    
                int random = 1 + (rand() % length() - 1); 
                Type temp = list[i];
                list [i] = list[random];
                list[random] = temp;    
        }   
}

/*------------------------------------------------------------*/
/*  *print-to-file()   -->  print output to a file            */
/*------------------------------------------------------------*/
template <class Type> 
void queue_array<Type>::print_to_file() {

        ofstream file("output1.txt");
        if( file.good() ) { 
    
                for(int i=0; i<length(); i++) {
                        file  << list[i] << " "; //write to the file
                }   
                file << endl; 
                file.close(); //close the file

        } else {
    
                cout << "ERROR: cannot open file for writing " << endl; 
        }   

}












